package com.nondo.rdp.auth.security.auth;

import com.nondo.rdp.auth.security.exceptions.JwtSignException;
import org.apache.tomcat.util.codec.binary.Base64;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.util.UUID;

/**
 * Hmac signer
 * Created by Michael DESIGAUD on 15/02/2016.
 */
public class JwtSigner {

    /**
     * Generate a random token (based on uuid)
     *
     * @return a random token
     */
    private static String generateToken() {
        return UUID.randomUUID().toString();
    }

    /**
     * Generate a random secret (base on uuid) and encoded in base 64
     *
     * @return a random secret
     */
    public static String generateSecret() {
        try {
            return Base64.encodeBase64String(generateToken().getBytes("UTF-8")).replace("\n", "").replace("\r", "");
        } catch (UnsupportedEncodingException ignored) {
            return generateToken();
        }
    }

    /**
     * Encodes a message with HMAC and a given algorithm
     *
     * @param secret    secret used to sign the message
     * @param message   message to sign
     * @param algorithm algorithm ued to sign
     * @return an HMAC encoded string
     * @throws JwtSignException
     */
    public static String encodeMac(final String secret, final String message, final String algorithm) throws JwtSignException {
        String digest;
        try {
            SecretKeySpec key = new SecretKeySpec(secret.getBytes("UTF-8"), algorithm);
            Mac mac = Mac.getInstance(algorithm);
            mac.init(key);

            byte[] bytes = mac.doFinal(message.getBytes("UTF-8"));

            StringBuilder hash = new StringBuilder();
            for (byte b : bytes) {
                String hex = Integer.toHexString(0xFF & b);
                if (hex.length() == 1) {
                    hash.append('0');
                }
                hash.append(hex);
            }
            digest = hash.toString();
        } catch (Exception ex) {
            throw new JwtSignException("Error while encoding request with hmac", ex);
        }
        return digest;
    }
}
